#include <assert.h>
#include <string.h>
#include <stdio.h>

#include "stack.h"

const size_t STACK_INIT_SIZE = 2;

Stack::Stack() : _size(STACK_INIT_SIZE), _top(0)
{
	_data = new int[_size];
}

Stack::Stack( size_t size ) : _top(0)
{
	_size = size;
	_data = new int[_size];
	memset( _data, 0, _size );
}

Stack::Stack( const Stack& st )
{
	_top = st._top;
	_size = st._size;
	_data = new int[_size];
	_data = (int*)memcpy( _data, st._data, sizeof(int)*_size );
}

Stack& Stack::operator=( const Stack& st )
{
	if( this == &st )
		return *this;
	delete [] _data;
	_top = st._top;
	_size = st._size;
	_data = new int[_size];
	_data = (int*)memcpy( _data, st._data, sizeof(int)*_size );
	return *this;
}

Stack::~Stack()
{
	if( _data != NULL )
		delete [] _data;
}

size_t Stack::size()
{
	return _top;
}

void Stack::push( int v )
{
	extendOnDemand();
	_data[_top++] = v;
}

int Stack::pop()
{
	if( empty() )
		throw StackEmptyException();
	return _data[--_top];
}

bool Stack::empty()
{
	return _top == 0;
}

void Stack::extendOnDemand()
{
	if( _top == _size )
	{
		size_t newSize = _size * 2;
		int* newData = new int[newSize];
		newData = (int*)memcpy( newData, _data, sizeof(int)*_size );
		delete _data;
		_data = newData;
		_size = newSize;
	}
}
